﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VoxelBlock;using Vector3Int = VoxelBlock.Vector3Int;
using VoxelBlock.VoxelBlock3D;

public class TestCamera : MonoBehaviour {

    public Material m_Material;

    public Vector3 ScreenToWorldPoint;
    public Vector3 mousePosition;
    public float mousePositionZ;
    public float test001 = 10;
    public Camera camera;
    public GameObject cube;

    public float m_UnitSize = 10;
    VoxelEditorMastermind m_VoxelEditorMastermind;
    void Start () {
        m_VoxelEditorMastermind = VoxelEditorMastermind.instance;
    }
    Dictionary<Vector3Int, Voxel3D> allp = new Dictionary<Vector3Int, Voxel3D>();
    //List<Vector3Int> allPlist = new List<Vector3Int>();
    Vector3Int[] oldPlist = new Vector3Int[0];

    [SerializeField]
    LayerMask layerMask;

    Texture2D texture;
    void Update () {
        //mousePosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, mousePositionZ);
        //ScreenToWorldPoint = camera.ScreenToWorldPoint(mousePosition);
        //cube.transform.position = ScreenToWorldPoint;
        if (Input.GetKeyDown(KeyCode.D))
        {
            m_VoxelEditorMastermind.TestRemove(oldPlist);
            allp.Clear();

            Vector3 mousePosition_Item1 = new Vector3(Input.mousePosition.x, Input.mousePosition.y, mousePositionZ);
            Vector3 ScreenToWorldPoint_Item1 = camera.ScreenToWorldPoint(mousePosition_Item1);
            Vector3 mousePosition_Item2 = new Vector3(Input.mousePosition.x, Input.mousePosition.y, mousePositionZ + test001);
            Vector3 ScreenToWorldPoint_Item2 = camera.ScreenToWorldPoint(mousePosition_Item2);

            var list = BasicAlgorithm.GetLineBlock3D(Round(ScreenToWorldPoint_Item1) , Round(ScreenToWorldPoint_Item2));
            foreach (var item in list)
            {
                allp[item] = new Voxel3D(item, 3);
            }

            oldPlist = m_VoxelEditorMastermind.TestAdd(allp.Values);
        }
        if (Input.GetKeyDown(KeyCode.A))
        {
            m_VoxelEditorMastermind.TestRemove(oldPlist);
            allp.Clear();
            float unitX = Screen.width  / m_UnitSize;
            float unitY = Screen.height / m_UnitSize;
            for (float x = -unitX; x <= Screen.width + unitX; x+= unitX)
            {
                for (float y = -unitX; y <= Screen.height + unitX; y += unitY)
                {
                    Vector3 item = camera.ScreenToWorldPoint(new Vector3(x, y, mousePositionZ));
                    Vector3Int itemInt = new Vector3Int(Mathf.Round(item.x), Mathf.Round(item.y), Mathf.Round(item.z));
                    allp[itemInt] = new Voxel3D(itemInt ,3);
                }
            }
            oldPlist = m_VoxelEditorMastermind.TestAdd(allp.Values);
        }
        if (Input.GetKeyDown(KeyCode.Z))
        {
            //m_VoxelEditorMastermind.TestRemove(oldPlist);
            //allp.Clear();

            {
                m_VoxelEditorMastermind.TestRemove(oldPlist);
                allp.Clear();
                float unitX_ = Screen.width / m_UnitSize;
                float unitY_ = Screen.height / m_UnitSize;
                for (float x = -unitX_; x <= Screen.width + unitX_; x += unitX_)
                {
                    for (float y = -unitY_; y <= Screen.height + unitY_; y += unitY_)
                    {
                        Vector3 item = camera.ScreenToWorldPoint(new Vector3(x, y, mousePositionZ + 30));
                        Vector3Int itemInt = new Vector3Int(Mathf.Round(item.x), Mathf.Round(item.y), Mathf.Round(item.z));
                        allp[itemInt] = new Voxel3D(itemInt, 3);
                    }
                }
                oldPlist = m_VoxelEditorMastermind.TestAdd(allp.Values);
            }

            texture = new Texture2D(256, 256);
            Texture2D EditingTex = m_VoxelEditorMastermind.EditingTex;
            Color[] colors = m_VoxelEditorMastermind.EditingTex.GetPixels();
            float startX = (Screen.width - Screen.height) / 2f;
            float unitX = Screen.height / 256f;
            float unitY = Screen.height / 256f;
            for (int x = 0; x < 256 ; x ++)
            {
                for (int y = 0; y < 256; y ++)
                {
                    float ScreenX = x * unitX + startX;
                    float ScreenY = y * unitY;
                    Vector3 item = camera.ScreenToWorldPoint(new Vector3(ScreenX, ScreenY, mousePositionZ));
                    Vector3Int itemInt = new Vector3Int(Mathf.Round(item.x), Mathf.Round(item.y), Mathf.Round(item.z));

                    //Vector3 item2 = camera.ScreenToWorldPoint(new Vector3(ScreenX, ScreenY, mousePositionZ + 新气功炮));
                    //Vector3Int itemInt2 = new Vector3Int(Mathf.Round(item2.x), Mathf.Round(item2.y), Mathf.Round(item2.z));

                    Ray uiCameraRay = camera.ScreenPointToRay(new Vector3(ScreenX, ScreenY, mousePositionZ));
                    RaycastHit objhit;
                    if (Physics.Raycast(uiCameraRay, out objhit, test001, layerMask))
                    {
                        var colorP2 = objhit.textureCoord;
                        var normal = objhit.normal;
                        Color shadow = Color.white;
                        if (normal.x !=0)
                        {
                            shadow = new Color(0.6f, 0.6f, 0.6f);
                        }
                        else if (normal.y != 0)
                        {
                            shadow = new Color(1, 1, 1);
                        }
                        else if (normal.z != 0)
                        {
                            shadow = new Color(0.8f, 0.8f, 0.8f);
                        }

                        //int uvKey = (int)(colorP2.x * 8 + colorP2.y * 32 * 8);
                        Vector2Int colorP2Int = new Vector2Int(colorP2.x * 8, colorP2.y * 32);
                        texture.SetPixel(x, y, EditingTex.GetPixel(colorP2Int.x, colorP2Int.y) * shadow);//colors[uvKey]);
                    }
                    //var list = BasicAlgorithm.GetLineBlock3D(itemInt, itemInt2);
                    //foreach (var itemz in list)
                    //{
                    //    allp[itemz] = new Voxel3D(itemz, 3);
                    //}
                    //int uvKey = GetLineBlock3D(itemInt, itemInt2);
                    //if (uvKey != -1)
                    //{
                    //    //allp[itemInt] = new Voxel3D(itemInt, uvKey);
                    //    texture.SetPixel(x , y, colors[uvKey]);
                    //}
                }
            }
             texture.Apply();
             m_Material.mainTexture = texture;
             //oldPlist = m_VoxelEditorMastermind.TestAdd(allp.Values);
        }
        //TestRead
    }


    Vector3Int Round(Vector3 item)
    {
        return new Vector3Int(Mathf.Round(item.x), Mathf.Round(item.y), Mathf.Round(item.z));
    }

    public int GetLineBlock3D(Vector3Int v1, Vector3Int v2)
    {
        //List<Vector3Int> V3S = new List<Vector3Int>();
        if (v1 == v2)
        {
            //V3S.Add(v1);
            return 0;
        }
        float x1 = v1.x;
        float y1 = v1.y;
        float z1 = v1.z;
        float x2 = v2.x;
        float y2 = v2.y;
        float z2 = v2.z;
        float MaxX;
        float MinX;
        float MaxY;
        float MinY;
        float MaxZ;
        float MinZ;
        if (x1 < x2)
        {
            MaxX = x2;
            MinX = x1;
        }
        else
        {
            MaxX = x1;
            MinX = x2;
        }

        if (y1 < y2)
        {
            MaxY = y2;
            MinY = y1;
        }
        else
        {
            MaxY = y1;
            MinY = y2;
        }


        if (z1 < z2)
        {
            MaxZ = z2;
            MinZ = z1;
        }
        else
        {
            MaxZ = z1;
            MinZ = z2;
        }

        int forXYZ = 1;
        if (MaxX - MinX < MaxY - MinY && MaxZ - MinZ < MaxY - MinY)
        {
            forXYZ = 2;
        }

        if (MaxX - MinX < MaxZ - MinZ && MaxY - MinY < MaxZ - MinZ)
        {
            forXYZ = 3;
        }

        if (forXYZ == 1)
        {
            if (x1 - x2 != 0)
            {
                float slopeY = (float)(y1 - y2) / (float)(x1 - x2);
                float constantY = y1 - slopeY * x1;

                float slopeZ = (float)(z1 - z2) / (float)(x1 - x2);
                float constantZ = z1 - slopeZ * x1;

                for (float x = MinX; x <= MaxX; x++)
                {
                    float vy = slopeY * x + constantY;
                    float vz = slopeZ * x + constantZ;
                    var itemP = new Vector3Int(x, Mathf.Round(vy), Mathf.Round(vz));
                    var block = m_VoxelEditorMastermind.TestRead(itemP);
                    if (block == null)
                    {
                    }
                    else
                    {
                        return block.uvKey;
                    }
                }
            }
        }
        else if (forXYZ == 2)
        {
            if (y1 - y2 != 0)
            {
                float slopeX = (x1 - x2) / (y1 - y2);
                float constantX = x1 - slopeX * y1;

                float slopeZ = (z1 - z2) / (y1 - y2);
                float constantZ = z1 - slopeZ * y1;

                for (float y = MinY; y <= MaxY; y++)
                {
                    float vz = slopeZ * y + constantZ;
                    float vx = slopeX * y + constantX;
                    //V3S.Add(new Vector3Int(Mathf.Round(vx), y, Mathf.Round(vz)));
                    var itemP = (new Vector3Int(Mathf.Round(vx), y, Mathf.Round(vz)));
                    var block = m_VoxelEditorMastermind.TestRead(itemP);
                    if (block == null)
                    {
                    }
                    else
                    {
                        return block.uvKey;
                    }
                }
            }
        }
        else if (forXYZ == 3)
        {
            if (z1 - z2 != 0)
            {
                float slopeX = (x1 - x2) / (z1 - z2);
                float constantX = x1 - slopeX * z1;

                float slopeY = (y1 - y2) / (z1 - z2);
                float constantY = y1 - slopeY * z1;

                for (float z = MinZ; z <= MaxZ; z++)
                {
                    float vy = slopeY * z + constantY;
                    float vx = slopeX * z + constantX;
                    //V3S.Add(new Vector3Int(Mathf.Round(vx), Mathf.Round(vy), z));
                    var itemP = (new Vector3Int(Mathf.Round(vx), Mathf.Round(vy), z));
                    var block = m_VoxelEditorMastermind.TestRead(itemP);
                    if (block == null)
                    {
                    }
                    else
                    {
                        return block.uvKey;
                    }
                }
            }
        }
        return -1;
    }


}
